/*
    XTU OJ: 1441
    by: fifth_light
*/

#include <stdio.h>
#include <string.h>
#include <assert.h>

int prime_table[168];

// 简单筛法
void prepare_table() {
    //                 0  1  2
    char table[998] = {1, 1, 0};
    for (int i = 2; i <= 32; i == 2 ? (i = 3) : (i += 2)) {
        for (int x = 4; x <= 997; x++) {
            if (x != i && x % i == 0) {
                table[x] = 1;
            }
        }
    }
    for (int c = 0, i = 0; i < 998; i++) {
        if (table[i] == 0) {
            prime_table[c++] = i;
        }
    }
}

typedef struct {
    int width;
    int height;
} rect;

rect bound;

rect calc_rect(int index) {
    rect result;
    if (index < 4) {
        switch(index) {
            case 0:
                result.width = 2;
                result.height = 1;
                break;
            case 1:
                result.width = 3;
                result.height = 3;
                break;
            case 2:
                result.width = 6;
                result.height = 4;
                break;
            case 3:
                result.width = 7;
                result.height = 8;
                break;
            default:
                assert(0);
        }
    } else {
        int number = prime_table[index];
        int prev_number = prime_table[index - 1];
        switch (index % 4) {
            // R
            case 0:
                result.width = number + 1;
                result.height = prev_number + 1;
                break;
            // U
            case 1:
                result.width = prev_number + 2;
                result.height = number;
                break;
            // L
            case 2:
                result.width = number + 1;
                result.height = prev_number + 1;
                break;
            // D
            case 3:
                result.width = prev_number + 2;
                result.height = number + 1;
                break;
            default:
                assert(0);
        }
    }
    return result;
}

typedef struct {
    int start_x;
    int start_y;
    int len;
} line;

char canvas[1000][1000] = {0};

void clear_canvas() {
    for (int i = 0; i < 1000; i++) {
        memset(canvas[i], 0, sizeof(char) * 1000);
    } 
}

// dir: 0为横向，1为纵向
void canvas_draw_line(line l, int dir) {
    // BREAKPOINT BELOW
    if (dir == 0) {
        for (int i = 0; i < l.len; i++) {
            canvas[l.start_y][l.start_x + i] = '_';
        }
    } else {
        for (int i = 0; i < l.len; i++) {
            canvas[l.start_y + i][l.start_x] = '|';
        }
    }
}

void output() {
    for (int y = 0; y < bound.height; y++) {
        int spaces = 0;
        for (int x = 0; x < bound.width; x++) {
            if (canvas[y][x] == '\0') {
                spaces++;
            } else {
                for (int sp = 0; sp < spaces; sp++) {
                    putchar(' ');
                }
                spaces = 0;
                putchar(canvas[y][x]);
            }
        }
        putchar('\n');
    }
}

void draw_line(int index, int start_x, int start_y) {
    // BREAKPOINT BELOW
    int next_x;
    int next_y;
    line l;
    l.len = prime_table[index];
    
    // 注意：反着来画线，所以下一条坐标计算方向与当前线走向相反
    switch (index % 4) {
        // R
        case 0:
            next_x = start_x - l.len;
            next_y = start_y;
            l.start_x = start_x - l.len + 1;
            l.start_y = start_y;
            canvas_draw_line(l, 0);
            break;
        // U
        case 1:
            next_x = start_x - 1;
            next_y = start_y + l.len - 1;
            l.start_x = start_x;
            l.start_y = start_y;
            canvas_draw_line(l, 1);
            break;
        // L
        case 2:
            next_x = start_x + l.len;
            next_y = start_y + 1;
            l.start_x = start_x;
            l.start_y = start_y;
            canvas_draw_line(l, 0);
            break;
        // D
        case 3:
            next_x = start_x + 1;
            next_y = start_y - l.len;
            l.start_x = start_x;
            l.start_y = start_y - l.len + 1;
            canvas_draw_line(l, 1);
            break;
        default:
            assert(0);
    }
    
    if (index > 0) {
        draw_line(index - 1, next_x, next_y);
    }
}

void draw(int index) {
    switch (index % 4) {
        // R
        case 0:
            draw_line(index, bound.width - 1, bound.height - 1);
            break;
        // U
        case 1:
            draw_line(index, bound.width - 1, 0);
            break;
        // L
        case 2:
            draw_line(index, 0, 0);
            break;
        // D
        case 3:
            draw_line(index, 0, bound.height - 1);
            break;
    }
}

int main(void) {
    prepare_table();
    int t;
    scanf("%d", &t);
    for(int i = 0; i < t; i++) {
        int n;
        scanf("%d", &n);
        n--;
        bound = calc_rect(n);
        // printf("width: %d, height: %d\n", bound.width, bound.height);
        draw(n);
        output();
        putchar('\n');
        clear_canvas();
    }
    return 0;
}
